#include "XString.h"
#include "Exception.h"

namespace platform {


XString::XString(const std::string &s) {
	WCHAR buf[1024];
	WCHAR *pbuf;
	int size;
	if (s.size() > 1024) {
		size = static_cast<int>(s.size()) + 128;
		pbuf = new WCHAR[size];
	} else {
		size = 1024;
		pbuf = buf;
	}

	int res = ::MultiByteToWideChar(CP_ACP, 0, s.c_str(), static_cast<int>(s.size()) + 1, pbuf, size);
	if (res <= 0)
		*pbuf = (WCHAR)0;
	*this = pbuf;

	if (pbuf != buf)
		delete[] pbuf;
}

void XString::split(TCHAR sep, XStringList &tokens) const {
	tokens.clear();

	const TCHAR *ptr = getTStr();
	const TCHAR *pos;
	while ((pos = _tcschr(ptr, sep)) != NULL) {
		tokens.push_back(XString(ptr, (pos-ptr)));
		ptr = pos + 1;
	}

	if (*ptr != _T('\0'))
		tokens.push_back(XString(ptr));
}


std::string XString::getANSIString(void) const
{
	char buf[1024];
	int res = ::WideCharToMultiByte(CP_ACP, 0, c_str(), -1, buf, 1024, NULL, NULL);
	if (res <= 0)
		buf[0] = '\0';
	return buf;
}


void XString::saveToStream(std::ostream &os) const {
	size_t slen = size();
	os.write(reinterpret_cast<const char*>(&slen), sizeof(slen));
	os.write(reinterpret_cast<const char*>(c_str()), static_cast<std::streamsize>(slen * sizeof(TCHAR)));

}

void XString::readFromStream(std::istream &is) {
	size_t slen;
	is.read(reinterpret_cast<char*>(&slen), sizeof(slen));
	if (is.fail())
		THROW(SerializationException, "failed to read XString from file");
	if (slen > 0) {
		reserve(slen);
		TCHAR *buf = new TCHAR[slen];
		is.read(reinterpret_cast<char*>(buf), static_cast<std::streamsize>(sizeof(TCHAR) * slen));
		append(buf, buf+slen);
		delete[] buf;
	}	
}

void XString::writeDebugInfo(std::ostream &os) const {
	os << '"' << getANSIString() << '"';
}


} // end namespace
